<template>
  <div class="code-show" ref="codeShow">
    <div class="code-show-left" ref="codeShowLeft">
      <el-tree
        ref="codeTree"
        :data="codeFolderList"
        :props="defaultProps"
        @node-click="handleNodeClick"
        :default-expand-all="false"
        :default-expanded-keys="defaultExpandedKeys"
      >
        <template #default="{ node }">
          <img src="./file.png" style="width: 16px; height: 16px" v-if="node.data.type == 'file'" />
          <img src="./folder.png" style="width: 16px; height: 16px" v-if="node.data.type == 'dir'" />
          &nbsp;
          <span>{{ node.label }}</span>
        </template>
      </el-tree>
    </div>
    <div class="code-show-middle" ref="codeShowMiddle"></div>
    <div class="code-show-right" ref="codeShowRight">
      <div class="code-show-right-content">
        <el-tabs
          v-model="editableTabsValue"
          type="card"
          class="demo-tabs"
          closable
          @tab-remove="removeTab"
          @tab-click="handleTabClick"
          v-if="editableTabs.length"
        >
          <el-tab-pane
            type="card"
            v-for="item in editableTabs"
            :key="item.name"
            :label="item.title"
            :name="item.name"
            @contextmenu.prevent="contextMenu"
          >
            <div class="code-show-area" v-html="highlightedCode"></div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";
import hljs from "highlight.js";
import codeFolder from "@/assets/code-folder.json";
//父组件传过来的项目名称，对应public文件夹下code-folder对应文件夹
const props = defineProps({
  projectName: {
    type: String,
    default: "ts_data_structure"
  }
});
//找到对应代码
const codeFolderList = ref(
  codeFolder.children.find(item => item.label === props.projectName)
    ? [codeFolder.children.find(item => item.label === props.projectName)]
    : []
);
//真正的代码
let highlightedCode = ref("");
interface Tree {
  label: string;
  children?: Tree[];
  content?: string;
  path?: string;
}
//左边文件的点击事件
const handleNodeClick = (data: Tree) => {
  debugger;
  if (data.content) {
    //如果是文件的话，打开文件源码
    let lan = "javascript";
    try {
      lan = data.label?.substring((data.label?.lastIndexOf(".") || -1) + 1) || "javascript";
      highlightedCode.value = hljs.highlight(data.content!, {
        language: lan
      }).value;
    } catch (e) {
      lan = "javascript";
      highlightedCode.value = hljs.highlight(data.content!, {
        language: lan
      }).value;
    }
    //判断右侧有没有此文件，没有的话，打开文件，有的话，找到对应位置
    const index = editableTabs.value.findIndex(item => item.name === data.path);
    if (index !== -1) {
      editableTabsValue.value = data.path!;
    } else {
      //打开文件
      editableTabs.value.push({
        title: data.label,
        name: data.path,
        content: data.content,
        label: data.label,
        path: data.path
      });
      editableTabsValue.value = data.path!;
    }
  }
};
//tab控制
const editableTabsValue = ref("");
const editableTabs = ref([] as any[]);
const removeTab = (targetName: string) => {
  debugger;
  let tabs = editableTabs.value;
  let tabIndex = tabs.findIndex(tab => tab.name === targetName);
  //如果此时有多个tab，则删除当前tab
  if (tabs.length > 1) {
    tabs.splice(tabIndex, 1);
    if (tabIndex == 0) {
      handleNodeClick(tabs[0]);
    } else {
      handleNodeClick(tabs[tabIndex - 1]);
    }
    return;
  } else {
    tabs.splice(0, 1);
  }
};
const handleTabClick = (item: any) => {
  let tabIndex = item.index;
  let target = editableTabs.value[tabIndex];

  if (editableTabsValue.value === target.name) {
    return;
  }
  handleNodeClick(target);
};
const defaultProps = {
  children: "children",
  label: "label"
};
const codeShow = ref(null);
const codeShowLeft = ref(null);
const codeShowRight = ref(null);
const codeShowMiddle = ref(null);
const handleResize = (leftMinWidth = 200, rightMinWidth = 200) => {
  const boxDom = codeShow.value! as any,
    leftDom = codeShowLeft.value! as any,
    resizeDom = codeShowMiddle.value! as any,
    rightDom = codeShowRight.value! as any;
  resizeDom.onmousedown = e => {
    const startX = e.clientX; // 记录坐标起始位置
    leftDom.left = leftDom.offsetWidth; // 左边元素起始宽度
    document.onmousemove = e => {
      const endX = e.clientX; // 鼠标拖动的终止位置
      let moveLen = leftDom.left + (endX - startX); // 移动的距离 =  endX - startX，左边区域最后的宽度 = resizeDom.left + 移动的距离
      const maxWidth = boxDom.clientWidth - resizeDom.offsetWidth; // 左右两边区域的总宽度 = 外层容器宽度 - 中间区域拖拉框的宽度
      // 限制左边区域的最小宽度为 leftMinWidth
      if (moveLen < leftMinWidth) {
        moveLen = leftMinWidth;
      }
      // 右边区域最小宽度为 rightMinWidth
      if (moveLen > maxWidth - rightMinWidth) {
        moveLen = maxWidth - rightMinWidth;
      }
      leftDom.style.width = (moveLen / maxWidth) * 100 + "%"; // 设置左边区域的宽度，通过换算为百分比的形式，实现窗体放大缩小自适应
      rightDom.style.width = ((maxWidth - moveLen) / maxWidth) * 100 + "%"; // 右边区域 = 总大小 - 左边宽度 - 拖动条宽度
    };
    document.onmouseup = () => {
      document.onmousemove = null;
      document.onmouseup = null;
      resizeDom.releaseCapture && resizeDom.releaseCapture(); // 鼠标捕获释放
    };
    resizeDom.setCapture && resizeDom.setCapture(); // 启用鼠标捕获
    return false;
  };
};
//右键菜单
const contextMenu = e => {
  console.log(e);
};
const defaultExpandedKeys = ref([] as any[]);
onMounted(() => {
  debugger;
  handleResize();
  //默认打开第一层级的第一个文件
  console.log(codeFolderList);
  // let treeData = codeFolderList.children;
  // if (codeFolderList.length > 0 && this.treeData[0].children && this.treeData[0].children.length > 0) {
  //   // 假设我们总是展开第一个元素的第一个子节点
  //   this.defaultExpandedKeys = [this.treeData[0].children[0].id];
  // }
  defaultExpandedKeys.value = ["1"];
});
</script>
<style scoped lang="scss">
$left-bgcolor: rgb(229 231 235);
$right-bgcolor: rgb(255 255 255);
:deep(.el-tree) {
  background-color: $left-bgcolor;
}
:deep(.el-tabs__nav-scroll) {
  background-color: $left-bgcolor;
}
:deep(.el-tabs__item.is-active) {
  background-color: $right-bgcolor;
}
:deep(.el-tabs) {
  display: flex;
  flex-direction: column;
  height: 100%;
  .el-tabs__content {
    flex: 1;
    overflow: auto;
  }
}
.code-show {
  display: flex;
  width: 100%;
  height: 60vh;
  .code-show-left {
    width: 250px;
    min-width: 250px;
    height: 100%;
    overflow: auto;
    background-color: $left-bgcolor;
  }
  .code-show-middle {
    width: 5px;
    height: 100%;
    background-color: rgb(221 216 216);
    &:hover {
      cursor: ew-resize;
    }
  }
  .code-show-right {
    flex: 1;
    width: calc(100% - 255px);
    height: 100%;
    background-color: $right-bgcolor;
    .code-show-right-content {
      width: 100%;
      height: 100%;
    }
    .code-show-area {
      padding-left: 12px;
      white-space: pre-wrap;
    }
  }
}
</style>
